<!--
 * @Description: 添加排放源
 * @Author: qingyang
 * @Date: 2022-03-23 17:10:03
 * @LastEditors: qingyang
 * @LastEditTime: 2023-03-06 17:40:00
-->
<template>
  <CDialog
    :title="inventoryFacilityNo ? '修改排放源' : '新增排放源'"
    append-to-body
    :close-on-click-modal="false"
    destroy-on-close
    :width="680"
    v-model:visible="dialogVisible"
    @confirm="handleConfirm"
    @cancel="dialogVisible = false"
    :loading="loading"
    :confirmText="inventoryFacilityNo ? '保存' : '新增'"
    :footer="!isReadOnly"
  >
    <el-form
      v-loading="pageLoading"
      class="edit-form"
      ref="formRef"
      :model="taskForm"
      :rules="rules"
      label-position="top"
      :inline="true"
      scroll-to-error
    >
      <el-row :gutter="20">
        <el-col :span="24">
          <el-form-item label="目录" prop="frameworkInfoList">
            <el-cascader
              :disabled="isReadOnly || isEdit"
              ref="cascaderRef"
              popper-class="cascader-wrap"
              v-model="taskForm.frameworkInfoList"
              :options="options"
              :props="cascaderProps"
              @change="nodeChange"
              filterable
            >
              <template #default="{ data }">
                <div class="g-flex-between-center">
                  <span>{{ data.frameworkName }}</span>
                  <span class="framework-disabled-text" v-if="data.disabled">暂无排放源</span>
                </div>
              </template>
            </el-cascader>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="排放源" prop="sourceName">
            <CSelect
              :disabled="selectDisable || isReadOnly || isEdit"
              v-model="taskForm.sourceName"
              filterable
              :placeholder="selectDisable ? '请先选择目录' : '请选择'"
              @change="handleSelect($event, 'FACTOR')"
              clearable
              @clear="clearAutocomplete"
            >
              <el-option
                v-for="item in dischargeList"
                :key="item.no"
                :label="item.name"
                :value="item.name"
              />
            </CSelect>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="能源/燃料" prop="materialName">
            <CSelect
              :disabled="selectDisable || isReadOnly || isEdit"
              v-model="taskForm.materialName"
              filterable
              :placeholder="selectDisable ? '请先选择目录' : '请选择'"
              @change="handleSelect($event, 'EMISSION_SOURCE')"
              clearable
              @clear="clearAutocomplete"
            >
              <el-option
                v-for="item in fuelList"
                :key="item.no"
                :label="item.name"
                :value="item.name"
              />
            </CSelect>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="单位" prop="dataUnit">
            <CSelect
              v-model="taskForm.dataUnit"
              ref="selectRef"
              :disabled="selectDisable || isReadOnly"
              :placeholder="selectDisable ? '请先选择目录' : '请选择'"
            >
              <el-option
                :label="item"
                :value="item"
                v-for="(item, index) in activeDataUnitOption"
                :key="index"
              ></el-option>
            </CSelect>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="设备型号" prop="facilityModel">
            <el-input
              placeholder="请输入"
              v-model="taskForm.facilityModel"
              clearable
              :disabled="isReadOnly"
            ></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="设备位置" prop="facilityLocation">
            <el-input
              placeholder="请输入"
              v-model="taskForm.facilityLocation"
              clearable
              :disabled="isReadOnly"
            ></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="数据来源" prop="dataOrigin">
            <CSelect
              v-model="taskForm.dataOrigin"
              placeholder="请选择"
              clearable
              :disabled="isReadOnly"
            >
              <el-option
                v-for="item in DataOriginOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </CSelect>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="负责部门" prop="chargeDepartment">
            <CSelect
              v-if="departmentOptions.length"
              v-model="taskForm.chargeDepartment"
              class="table-select"
              placeholder="请选择"
              filterable
              :disabled="isReadOnly"
            >
              <el-option
                v-for="item in departmentOptions"
                :key="item.id"
                :value="item.dataValue"
                :label="item.dataValue"
              >
              </el-option>
            </CSelect>
            <el-input
              v-else
              placeholder="请输入"
              v-model="taskForm.chargeDepartment"
              clearable
              :disabled="isReadOnly"
            ></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="仪器校正等级" prop="correctionGrade">
            <CSelect
              v-model="taskForm.correctionGrade"
              placeholder="请选择"
              clearable
              :disabled="isReadOnly"
            >
              <el-option
                v-for="item in CorrectionGradeOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </CSelect>
          </el-form-item>
        </el-col>
        <el-col :span="24" v-if="showMixedGasMaterialName.includes(taskForm.materialName)">
          <el-form-item label="混合气体占比" prop="mixedGasList" :rules="mixedGasListRules">
            <MixedGasList v-model="taskForm.mixedGasList" :readonly="isReadOnly"></MixedGasList>
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="绑定EMS">
            <el-radio-group v-model="taskForm.meterType" @change="changeRadio">
              <el-radio :label="item.value" v-for="item in MeterTypeOption" :key="item.value">
                {{ item.label }}
              </el-radio>
            </el-radio-group>
            <el-select
              v-model="taskForm.emsDeviceIds"
              multiple
              placeholder="请选择"
              v-if="taskForm.meterType"
            >
              <el-option
                v-for="item in emsOptions"
                :key="item.deviceNo"
                :label="item.meterName"
                :value="item.deviceNo"
                multiple
              >
                <COption
                  style="padding-right: 20px"
                  :name="item.plantName"
                  :subName="item.meterName"
                />
              </el-option>
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
  </CDialog>
</template>
<script lang="ts">
export default {
  name: 'AddFacilityDialog'
};
</script>
<script lang="ts" setup>
import { defineProps, withDefaults, defineEmits, computed, ref, watch, reactive } from 'vue';
import { CDialog } from '@/components/CDialog';
import { rules } from './rule';
import { useMessage } from '@/hooks/useMessage';
import { IListItem } from '@/apis/eci/discharge/model/dischargeFillModel';
import { IFactorType } from '@/apis/eci/discharge/model/dischargeFillModel';
import { COption } from '@/components/COption/index';
import {
  getSourceCatalog,
  getSourceFactorList,
  planFacilityEdit,
  planFacilitySave,
  getFacilityDetail,
  getEmsDevice
} from '@/apis/eci/inventory/inventory';
import { DataOriginOptions, CorrectionGradeOptions, MeterTypeOption } from '@/constants/enum';
import MixedGasList from '../MixedGasList/index.vue';
import discharge from '@/apis/eci/discharge/index';
import { isArray } from '@/utils/is';
import Decimal from 'decimal.js';
import { getSystemDict } from '@/apis/common/common';
import { CSelect } from '@/components/CSelect';
interface SelectFillTypeDialogProps {
  visible: boolean;
  inventoryFacilityNo?: string;
  inventoryNo: string;
  organizationCode: string;
  isReadOnly?: boolean;
}
const cascaderProps = {
  expandTrigger: 'hover',
  label: 'frameworkName',
  value: 'frameworkNo',
  children: 'childNodeList',
  disabled: 'disabled'
};
const props = withDefaults(defineProps<SelectFillTypeDialogProps>(), {
  isReadOnly: false
});
const emit = defineEmits(['update:visible', 'refresh']);
const isEdit = computed(() => {
  return !!props.inventoryFacilityNo;
});
const dialogVisible = computed<boolean>({
  get: () => {
    return props.visible;
  },
  set: val => {
    emit('update:visible', val);
  }
});
watch(
  () => dialogVisible.value,
  visible => {
    if (!visible) {
      init();
    } else {
      if (props.inventoryFacilityNo) {
        loadData(props.inventoryFacilityNo);
      }
    }
  }
);

const formRef = ref();
const options = ref<any[]>([]);
const loading = ref(false);
const pageLoading = ref(false);
const selectDisable = computed(() => {
  const hasNode = taskForm.frameworkInfoList && taskForm.frameworkInfoList.length > 0;
  return !hasNode;
});
const dischargeList = ref<IListItem[] | null>([]);
const fuelList = ref<IListItem[] | null>([]);
const dischargeListStatic = ref<IListItem[] | null>([]);
const fuelListStatic = ref<IListItem[] | null>([]);
const { createMessage } = useMessage();
const taskForm = reactive({
  frameworkInfoList: [] as string[],
  sourceName: '',
  sourceNo: '',
  materialName: '',
  materialNo: '',
  facilityName: '',
  facilityNo: '',
  facilityModel: '',
  facilityLocation: '',
  dataUnit: '',
  dataOrigin: 'PERIODIC',
  chargeDepartment: '',
  correctionGrade: 'FOLLOW_REGULATION',
  meterType: '',
  mixedGasList: [] as any[],
  emsDeviceIds: [] as string[]
});
const emsOptions = ref([] as any);
watch(
  () => taskForm.meterType,
  val => {
    if (val) {
      getEmsDevice(taskForm.meterType, props.organizationCode).then(res => {
        emsOptions.value = res;
      });
    }
  }
);
const initData = async () => {
  // 加载目录tree
  const res = await getSourceCatalog(3);
  function dfs(arr: any[]) {
    if (!arr?.length) return;
    for (let i = 0; i < arr.length; i++) {
      const item = arr[i];
      item.disabled = false;
      if (item.childNodeList?.length) {
        dfs(item.childNodeList);
      } else {
        item.disabled = !(item.emissionSourceFlag === true);
      }
    }
  }

  dfs(res);

  options.value = res;
  loadDepartmentOptions();
};
const loadData = async (inventoryFacilityNo: string) => {
  pageLoading.value = true;
  try {
    const params = {
      inventoryFacilityNo,
      inventoryNo: props.inventoryNo
    };
    const data = await getFacilityDetail(params);
    const catalogNo = data.catalogInfo[data.catalogInfo.length - 1];
    await fetchSourceFactorList(catalogNo, 'ALL');
    if (dischargeList.value) {
      const sourceIndex = dischargeList.value.findIndex(item => item.name == data.sourceName);
      if (sourceIndex > -1) {
        taskForm.sourceNo = dischargeList.value[sourceIndex].no;
      }
    }
    if (fuelList.value) {
      const factorIndex = fuelList.value.findIndex(item => item.name == data.materialName);
      if (factorIndex > -1) {
        taskForm.materialNo = fuelList.value[factorIndex].no;
      }
    }
    taskForm.frameworkInfoList = data.catalogInfo;
    taskForm.sourceName = data.sourceName;
    taskForm.materialName = data.materialName;
    taskForm.facilityName = data.facilityName;
    taskForm.facilityNo = data.facilityNo;
    taskForm.facilityModel = data.facilityModel;
    taskForm.facilityLocation = data.facilityLocation;
    taskForm.dataUnit = data.dataUnit;
    taskForm.dataOrigin = data.dataOrigin;
    taskForm.chargeDepartment = data.chargeDepartment;
    taskForm.correctionGrade = data.correctionGrade;
    taskForm.emsDeviceIds = data.emsDeviceIds;
    taskForm.meterType = data.emsMeterType || '';
    taskForm.mixedGasList =
      data.mixedGasList?.map(item => {
        return {
          ...item,
          ratio: Decimal.mul(item.ratio, 100).toNumber()
        };
      }) || [];

    if (catalogNo && taskForm.sourceName && taskForm.materialName) {
      const paramsUnit = {
        frameworkNo: catalogNo,
        sourceName: taskForm.sourceName,
        materialName: taskForm.materialName
      };
      let unitArr = await discharge.getDischargeUnit(paramsUnit);
      activeDataUnitOption.value = unitArr;
    }
  } finally {
    pageLoading.value = false;
  }
};
const departmentOptions = ref<any[]>([]);
const loadDepartmentOptions = async () => {
  let data = await getSystemDict('inventory:department');
  departmentOptions.value = data ?? [];
};
initData();
function handleConfirm() {
  formRef.value?.validate(async (valid: boolean, val: any) => {
    if (valid) {
      loading.value = true;
      try {
        const params = {
          inventoryNo: props.inventoryNo,
          inventoryFacilityNo: props.inventoryFacilityNo,
          facilityName: taskForm.facilityName,
          facilityNo: taskForm.facilityNo,
          facilityModel: taskForm.facilityModel,
          facilityLocation: taskForm.facilityLocation,
          dataUnit: taskForm.dataUnit,
          dataOrigin: taskForm.dataOrigin,
          chargeDepartment: taskForm.chargeDepartment,
          correctionGrade: taskForm.correctionGrade,
          frameworkInfoList: taskForm.frameworkInfoList,
          sourceNo: taskForm.sourceNo,
          sourceName: taskForm.sourceName,
          materialNo: taskForm.materialNo,
          materialName: taskForm.materialName,
          emsDeviceIds: taskForm.emsDeviceIds,
          emsMeterType: taskForm.emsDeviceIds?.length ? taskForm.meterType : undefined
        };
        if (taskForm.sourceName === '二氧化碳保护焊') {
          Object.assign(params, {
            mixedGasList: taskForm.mixedGasList?.map(item => {
              return {
                ...item,
                ratio: Decimal.div(item.ratio || 0, 100).toNumber()
              };
            })
          });
        } else {
          Object.assign(params, {
            mixedGasList: []
          });
        }
        if (isEdit.value) {
          await planFacilityEdit(params);
        } else {
          await planFacilitySave(params);
        }
        createMessage.success(
          props.inventoryFacilityNo ? '修改排放源设施成功！' : '添加排放源设施成功！'
        );
        dialogVisible.value = false;
        emit('refresh', taskForm.frameworkInfoList[taskForm.frameworkInfoList.length - 1]);
        init();
      } finally {
        loading.value = false;
      }
    }
  });
}
function init() {
  // 初始化数据
  loading.value = false;
  formRef.value?.resetFields();
  taskForm.mixedGasList = [];
  taskForm.emsDeviceIds = [];
  taskForm.meterType = '';
}

const changeRadio = () => {
  taskForm.emsDeviceIds = [];
};
const cascaderRef = ref();
const activeDataUnitOption = ref<string[]>([]);
const nodeChange = async (values: string[]) => {
  const frameworkNo = values[values.length - 1];
  await fetchSourceFactorList(frameworkNo, 'ALL');
  // 目录变化则初始化相关变量
  taskForm.sourceName = '';
  taskForm.materialName = '';
  taskForm.dataUnit = '';
  setTimeout(() => {
    formRef.value.clearValidate('sourceName');
    formRef.value.clearValidate('materialName');
    formRef.value.clearValidate('dataUnit');
  }, 0);
};

const handleSelect = async (name: string, type: IFactorType) => {
  if (name) {
    let catalogNo = taskForm.frameworkInfoList[taskForm.frameworkInfoList.length - 1];
    await fetchSourceFactorList(catalogNo, type, name, true);
    if (catalogNo && taskForm.sourceName && taskForm.materialName) {
      const paramsUnit = {
        frameworkNo: catalogNo,
        sourceName: taskForm.sourceName,
        materialName: taskForm.materialName
      };
      let unitArr = await discharge.getDischargeUnit(paramsUnit);
      activeDataUnitOption.value = unitArr;
      if (activeDataUnitOption.value?.length === 1) {
        // 只有一个单位时，默认选中
        taskForm.dataUnit = activeDataUnitOption.value[0];
      } else if (
        activeDataUnitOption.value?.length &&
        taskForm.dataUnit &&
        !activeDataUnitOption.value.includes(taskForm.dataUnit)
      ) {
        // 已选中的项与接口返回的列表不一致时，重置选中的值
        taskForm.dataUnit = '';
      }
    }
    if (type === 'EMISSION_SOURCE') {
      getMixedGasWhenMaterialName(name);
    }
  }
};
const clearAutocomplete = () => {
  if (!taskForm.sourceName && !taskForm.materialName) {
    dischargeList.value = dischargeListStatic.value;
    fuelList.value = fuelListStatic.value;
  } else if (taskForm.sourceName && !taskForm.materialName) {
    dischargeList.value = dischargeListStatic.value;
  } else if (!taskForm.sourceName && taskForm.materialName) {
    fuelList.value = fuelListStatic.value;
  }
};

const fetchSourceFactorList = async (
  catalogNo: string,
  type: IFactorType,
  name?: string,
  isSelected = false
) => {
  const params = {
    catalogNo,
    type,
    name
  };
  if (type == 'FACTOR' && dischargeList.value) {
    const index = dischargeList.value.findIndex(item => item.name == name);
    if (index > -1) {
      taskForm.sourceNo = dischargeList.value[index].no;
    }
  }
  if (type == 'EMISSION_SOURCE' && fuelList.value) {
    const index = fuelList.value.findIndex(item => item.name == name);
    if (index > -1) {
      taskForm.materialNo = fuelList.value[index].no;
    }
  }
  try {
    let { factorList, sourceList } = await getSourceFactorList(params);
    if (type == 'ALL') {
      fuelListStatic.value = factorList;
      dischargeListStatic.value = sourceList;
    }
    if (sourceList) {
      dischargeList.value = sourceList;
      if (isSelected) {
        // 只有一个排放源时，默认选中
        if (sourceList?.length === 1) {
          taskForm.sourceNo = sourceList[0].no;
          taskForm.sourceName = sourceList[0].name;
          const params2 = {
            catalogNo,
            type: 'FACTOR' as IFactorType,
            name: taskForm.sourceName
          };
          const res = await getSourceFactorList(params2);
          fuelList.value = res?.factorList || [];
        }
      }
    }
    if (factorList) {
      fuelList.value = factorList;
      if (isSelected) {
        // 只有一个能源/燃料时，默认选中
        if (factorList?.length === 1) {
          taskForm.materialNo = factorList[0].no;
          taskForm.materialName = factorList[0].name;
          const params2 = {
            catalogNo,
            type: 'EMISSION_SOURCE' as IFactorType,
            name: taskForm.materialName
          };
          const res = await getSourceFactorList(params2);
          dischargeList.value = res?.sourceList || [];
        }
      }
    }
    return Promise.resolve();
  } catch {
    return Promise.reject();
  }
};

const showMixedGasMaterialName = ['二氧化碳保护焊-CO2纯气体', '二氧化碳保护焊-CO2混合气体'];

function getMixedGasWhenMaterialName(materialName: string) {
  if (materialName === showMixedGasMaterialName[0]) {
    taskForm.mixedGasList = [
      {
        gas: 'CO2',
        ratio: 100,
        molarMass: 44
      }
    ];
  } else if (materialName === showMixedGasMaterialName[1]) {
    taskForm.mixedGasList = [
      {
        gas: 'CO2',
        ratio: '',
        molarMass: 44
      },
      {
        gas: 'Ar',
        ratio: '',
        molarMass: 40
      }
    ];
  } else {
    taskForm.mixedGasList = [];
  }
}

/**
 * 混合气体体积表单校验
 */
const validateMixedGasList = (rule: any, value: any, callback: any) => {
  if (value && isArray(value) && value.length) {
    let sum = 0;
    for (let i = 0; i < value.length; i++) {
      console.log('value[i].ratio', value[i].ratio);
      if (!value[i].ratio && value[i].ratio !== 0 && value[i].ratio !== '0') {
        return callback(new Error('请填写完整'));
      }
      if (Number(value[i].ratio) > 100 || Number(value[i].ratio) < 0) {
        return callback(new Error('请输入0-100之间的数值'));
      }
      sum = Decimal.add(sum, value[i].ratio || 0).toNumber();
    }
    if (sum !== 100) {
      callback(new Error('气体体积占比之和需等于100%'));
    } else {
      callback();
    }
  } else {
    callback();
  }
};

const mixedGasListRules = [
  {
    validator: validateMixedGasList,
    trigger: ['submit', 'blur', 'change']
  }
];
</script>
<style lang="scss" scoped>
.edit-form {
  width: 650px;
  :deep(.el-row) {
    width: 100%;
  }
}
:deep(.el-form-item) {
  margin-right: 0 !important;
  .el-cascader,
  .el-autocomplete,
  .CSelect {
    width: 100%;
  }
}
.framework-disabled-text {
  font-size: 12px;
  color: #7a8a99;
}
</style>

<style lang="scss">
.cascader-wrap {
  .el-cascader-menu {
    min-width: 227px !important;
  }
}
</style>
